package com.xaicode.auth.service.impl;

import cn.hutool.core.collection.CollUtil;
import cn.hutool.core.util.StrUtil;
import com.xaicode.auth.base.BaseMpServiceImpl;
import com.xaicode.auth.constant.EnableEnum;
import com.xaicode.auth.entity.SysRole;
import com.xaicode.auth.entity.SysRoleDept;
import com.xaicode.auth.entity.SysRoleMenu;
import com.xaicode.auth.mapper.SysRoleMapper;
import com.xaicode.auth.security.domain.dto.SysRoleDto;
import com.xaicode.auth.security.domain.params.SysRoleQueryParam;
import com.xaicode.auth.security.scope.DataScopeType;
import com.xaicode.auth.service.ISysRoleService;
import com.baomidou.mybatisplus.core.conditions.query.LambdaQueryWrapper;
import com.baomidou.mybatisplus.core.toolkit.Wrappers;
import com.github.pagehelper.PageInfo;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.stereotype.Service;
import org.springframework.transaction.annotation.Transactional;

import java.util.List;
import java.util.Objects;
import java.util.stream.Collectors;

@Service
public class SysRoleServiceImpl extends BaseMpServiceImpl<SysRoleMapper, SysRole> implements ISysRoleService {

    @Autowired
    SysRoleMapper sysRoleMapper;


    @Override
    public PageInfo<SysRole> queryPage(SysRoleQueryParam query) {
        startPage(query);
        List<SysRole> list = queryList(query);
        return PageInfo.of(list);
    }

    @Override
    public List<SysRole> queryList(SysRoleQueryParam query) {
        LambdaQueryWrapper<SysRole> lqw = Wrappers.lambdaQuery();
        lqw.eq(StrUtil.isNotBlank(query.getRoleName()), SysRole::getRoleName, query.getRoleName());
        List<SysRole> list = list(lqw);
        return list;
    }

    @Transactional(rollbackFor = Exception.class)
    @Override
    public void createRole(SysRoleDto entity) {

        // 处理默认数据权限
        if (Objects.isNull(entity.getDataScope())) {
            // 默认仅查询自身数据 code=5
            entity.setDataScope(DataScopeType.DATA_SCOPE_SELF.getCode());
        }

        save(entity);

        // 保存角色菜单关联
        if (CollUtil.isNotEmpty(entity.getMenuIds())) {
            List<SysRoleMenu> roleMenus = entity.getMenuIds().stream()
                    .map(menuId -> {
                        SysRoleMenu sysRoleMenu = new SysRoleMenu();
                        sysRoleMenu.setRoleId(entity.getId());
                        sysRoleMenu.setMenuId(menuId);
                        return sysRoleMenu;
                    }).collect(Collectors.toList());
            sysRoleMapper.insertBatchRoleMenu(roleMenus);
        }
    }

    @Transactional(rollbackFor = Exception.class)
    @Override
    public void updateRole(SysRoleDto entity) {
        updateById(entity);

        if (entity.getOperAction() == null) {
            return;
        }

        // 1: 本次操作是更新角色菜单关联
        if (entity.getOperAction() == 1) {
            // 删除角色菜单关联，并重新进行关联
            sysRoleMapper.deleteRoleMenuByRoleId(entity.getId());
            if (CollUtil.isNotEmpty(entity.getMenuIds())) {
                List<SysRoleMenu> roleMenus = entity.getMenuIds().stream()
                        .map(menuId -> {
                            SysRoleMenu sysRoleMenu = new SysRoleMenu();
                            sysRoleMenu.setRoleId(entity.getId());
                            sysRoleMenu.setMenuId(menuId);
                            return sysRoleMenu;
                        }).collect(Collectors.toList());
                sysRoleMapper.insertBatchRoleMenu(roleMenus);
            }
        }

        // 2: 本次操作是更新角色部门关联
        if (entity.getOperAction() == 2) {
            // 删除角色部门关联，并重新进行关联
            sysRoleMapper.deleteRoleDeptByRoleId(entity.getId());
            if (CollUtil.isNotEmpty(entity.getDeptIds())) {
                List<SysRoleDept> roleDepts = entity.getDeptIds().stream()
                        .map(deptId -> {
                            SysRoleDept sysRoleDept = new SysRoleDept();
                            sysRoleDept.setRoleId(entity.getId());
                            sysRoleDept.setDeptId(deptId);
                            return sysRoleDept;
                        }).collect(Collectors.toList());
                sysRoleMapper.insertBatchRoleDept(roleDepts);
            }
        }
    }


    @Override
    public List<String> getRolePermissionByUserId(String userId) {
        List<SysRole> roles = sysRoleMapper.getRolePermissionByUserId(userId, EnableEnum.ENABLE.getCode());
        return roles.stream()
                .map(SysRole::getRoleKey)
                .distinct()
                .collect(Collectors.toList());
    }

    @Override
    public List<SysRole> getRolesByUserId(String userId) {
        return sysRoleMapper.getRolesByUserId(userId, EnableEnum.ENABLE.getCode());
    }

    @Override
    public List<Integer> getRoleIdsByUserId(String userId) {
        List<SysRole> roles = sysRoleMapper.getRolesByUserId(userId, EnableEnum.ENABLE.getCode());
        return roles.stream()
                .map(SysRole::getId)
                .distinct()
                .collect(Collectors.toList());
    }

    @Override
    public List<Integer> getMenuIdsByRoleId(Integer roleId) {
        List<SysRoleMenu> roleMenus = sysRoleMapper.getMenuIdsByRoleId(roleId);
        return roleMenus.stream()
                .map(SysRoleMenu::getMenuId)
                .distinct()
                .collect(Collectors.toList());
    }

    @Override
    public List<Integer> getDeptIdsByRoleId(Integer roleId) {
        List<SysRoleDept> roleMenus = sysRoleMapper.getDeptIdsByRoleId(roleId);
        return roleMenus.stream()
                .map(SysRoleDept::getDeptId)
                .distinct()
                .collect(Collectors.toList());
    }

}
